1
00:00:02,130 --> 00:00:05,070
状态实际上并不是 React 特有的概念

2
00:00:05,070 --> 00:00:08,080
但这也是 React 中的一个关键概念。

3
00:00:08,080 --> 00:00:09,830
在 ExpenseItem 中，

4
00:00:09,830 --> 00:00:12,650
我们有一个想要使用的场景

5
00:00:12,650 --> 00:00:15,440
那个内置的状态概念。

6
00:00:15,440 --> 00:00:17,050
因为这里的标题

7
00:00:17,050 --> 00:00:19,970
当 clickHandler 执行时它会改变

8
00:00:19,970 --> 00:00:23,670
实际上是应该产生的数据

9
00:00:23,670 --> 00:00:27,100
在这个组件中被重新评估

10
00:00:27,100 --> 00:00:31,050
并在发生变化时在屏幕上重新绘制，

11
00:00:31,050 --> 00:00:33,083
当标题数据发生变化时。

12
00:00:34,280 --> 00:00:38,200
默认情况下，像这样的常规变量，

13
00:00:38,200 --> 00:00:42,350
不会触发此类重新评估。

14
00:00:42,350 --> 00:00:44,530
React 并不关心这个。

15
00:00:44,530 --> 00:00:47,430
如果你的组件函数中有一个变量

16
00:00:47,430 --> 00:00:51,060
并且该变量发生变化，React 会忽略它。

17
00:00:51,060 --> 00:00:54,580
它不关心这个，代码执行，当然，

18
00:00:54,580 --> 00:00:57,910
但整体组件函数不再执行

19
00:00:57,910 --> 00:01:00,840
只是因为某些变量发生了变化。

20
00:01:00,840 --> 00:01:04,200
顺便说一句，即使它会再次执行，

21
00:01:04,200 --> 00:01:06,460
当然然后标题，这个变量，

22
00:01:06,460 --> 00:01:08,470
一切都会被撤退

23
00:01:08,470 --> 00:01:11,350
并重新初始化为 props 值。

24
00:01:11,350 --> 00:01:13,690
因为作为该组件功能的一部分

25
00:01:13,690 --> 00:01:16,690
我们正在创建这个标题变量。

26
00:01:16,690 --> 00:01:18,180
所以即使会发生这种情况

27
00:01:18,180 --> 00:01:20,520
我们达不到预期的结果

28
00:01:20,520 --> 00:01:22,370
但我们甚至不需要考虑这个

29
00:01:22,370 --> 00:01:24,020
因为它没有发生。

30
00:01:24,020 --> 00:01:26,870
该 ExpenseItem 组件当前功能

31
00:01:26,870 --> 00:01:30,890
初始渲染后不会再次调用

32
00:01:30,890 --> 00:01:32,650
只是因为发生了点击

33
00:01:32,650 --> 00:01:34,420
或者因为变量改变了

34
00:01:34,420 --> 00:01:37,783
不会触发该组件函数再次运行。

35
00:01:39,400 --> 00:01:42,500
所以要告诉 React 它应该再次运行它，

36
00:01:42,500 --> 00:01:46,590
我们需要从 React 库导入一些东西。

37
00:01:46,590 --> 00:01:50,490
我们通过添加所谓的命名导入来做到这一点。

38
00:01:50,490 --> 00:01:53,510
这是默认导入。

39
00:01:53,510 --> 00:01:54,790
现在，我们可以添加一个逗号

40
00:01:54,790 --> 00:01:58,170
和大括号以及大括号之间

41
00:01:58,170 --> 00:02:02,030
我们现在可以提取具体命名的东西

42
00:02:02,030 --> 00:02:04,210
来自反应库。

43
00:02:04,210 --> 00:02:06,860
这里我们导入了整个React对象，

44
00:02:06,860 --> 00:02:11,690
现在我们要从 React 库导入单个片段。

45
00:02:11,690 --> 00:02:14,930
我们想在这里导入一个函数，

46
00:02:14,930 --> 00:02:17,293
一个名为 useState 的函数。

47
00:02:19,520 --> 00:02:22,580
这是React库提供的函数

48
00:02:22,580 --> 00:02:26,530
这个函数允许我们定义值

49
00:02:26,530 --> 00:02:31,530
作为这些值的变化应反映的状态

50
00:02:32,070 --> 00:02:34,500
在再次调用的组件函数中，

51
00:02:34,500 --> 00:02:36,030
这是一个关键的区别

52
00:02:36,030 --> 00:02:39,120
到我们在这里使用的常规变量。

53
00:02:39,120 --> 00:02:42,310
现在，我们如何使用这个 useState 函数呢？

54
00:02:42,310 --> 00:02:44,020
嗯，这很简单。

55
00:02:44,020 --> 00:02:47,660
在我们的组件函数内部，这一点很重要，

56
00:02:47,660 --> 00:02:50,580
我们必须在这个函数内部做到这一点。

57
00:02:50,580 --> 00:02:52,483
我们只需调用 useState 即可。

58
00:02:53,546 --> 00:02:57,280
而 useState 就是所谓的 React hook。

59
00:02:57,280 --> 00:02:59,530
还有其他的钩子，

60
00:02:59,530 --> 00:03:01,040
当然我们要学习

61
00:03:01,040 --> 00:03:03,430
关于本课程中所有重要的内容

62
00:03:03,430 --> 00:03:06,250
但这是最重要的之一。

63
00:03:06,250 --> 00:03:09,360
所有这些 React hooks 都可以被识别

64
00:03:09,360 --> 00:03:12,500
事实上它们以“use”这个词开头

65
00:03:12,500 --> 00:03:13,600
以他们的名义，

66
00:03:13,600 --> 00:03:17,370
所有这些钩子只能被调用

67
00:03:17,370 --> 00:03:21,430
React 组件函数（如 ExpenseItem）内部。

68
00:03:21,430 --> 00:03:26,320
不能像这样在这些函数之外调用它们。

69
00:03:26,320 --> 00:03:28,030
他们都不应该被称为

70
00:03:28,030 --> 00:03:29,750
在任何嵌套函数中。

71
00:03:29,750 --> 00:03:31,920
必须直接调用它们

72
00:03:31,920 --> 00:03:34,500
在此类组件函数中。

73
00:03:34,500 --> 00:03:36,780
有一个例外，我们稍后会讨论

74
00:03:36,780 --> 00:03:39,630
但目前，这是你应该记住的。

75
00:03:41,090 --> 00:03:44,230
现在，useState 并不像那样工作。

76
00:03:44,230 --> 00:03:48,570
相反，useState 一旦成为默认状态值，

77
00:03:48,570 --> 00:03:50,620
因为有了 useState

78
00:03:50,620 --> 00:03:54,220
我们基本上创建了一种特殊的变量，

79
00:03:54,220 --> 00:03:55,470
你可以说，

80
00:03:55,470 --> 00:03:58,350
变化将导致的变量

81
00:03:58,350 --> 00:04:00,850
该组件函数将被再次调用。

82
00:04:00,850 --> 00:04:04,140
当然我们可以分配一个初始值

83
00:04:04,140 --> 00:04:06,150
对于这个特殊变量，

84
00:04:06,150 --> 00:04:08,590
就像我们在这里赋值一样

85
00:04:08,590 --> 00:04:11,470
for 做常规变量。

86
00:04:11,470 --> 00:04:15,000
所以在这里，我的初始值是 props.title。

87
00:04:15,000 --> 00:04:18,533
我们只需将其作为参数传递给 useState 即可。

88
00:04:19,700 --> 00:04:22,900
现在是否创建了特殊变量。

89
00:04:22,900 --> 00:04:26,060
当然，我们也希望能够使用该变量，

90
00:04:26,060 --> 00:04:29,040
例如，我们希望能够在这里使用它

91
00:04:29,040 --> 00:04:33,120
因此 useState 也会返回一些东西。

92
00:04:33,120 --> 00:04:36,840
它使我们能够访问这个特殊变量。

93
00:04:36,840 --> 00:04:39,640
然而，它不仅仅返回，

94
00:04:39,640 --> 00:04:43,920
它还返回一个我们可以调用的函数

95
00:04:43,920 --> 00:04:46,963
为该变量分配新值。

96
00:04:48,120 --> 00:04:50,690
所以我们不会像这样分配值

97
00:04:50,690 --> 00:04:52,060
与等号，

98
00:04:52,060 --> 00:04:54,920
相反，我们将分配新值

99
00:04:54,920 --> 00:04:56,350
通过调用函数。

100
00:04:56,350 --> 00:05:01,090
这就是状态变量的工作原理。

101
00:05:01,090 --> 00:05:04,870
为此 useState 实际上返回一个数组

102
00:05:04,870 --> 00:05:09,540
其中第一个值是变量本身，

103
00:05:09,540 --> 00:05:12,070
你可以说，价值本身。

104
00:05:12,070 --> 00:05:14,220
以及数组中的第二个元素

105
00:05:14,220 --> 00:05:16,740
就是那个更新函数。

106
00:05:16,740 --> 00:05:19,890
我们可以使用现代 JavaScript 功能

107
00:05:19,890 --> 00:05:23,720
称为数组解构，看起来像这样，

108
00:05:23,720 --> 00:05:27,010
将两个元素存储在单独的变量中

109
00:05:27,010 --> 00:05:30,280
或常量，这里我将使用常量。

110
00:05:30,280 --> 00:05:33,483
我稍后会回到为什么它是一个常数。

111
00:05:34,330 --> 00:05:36,640
现在您可以选择任何您喜欢的名称

112
00:05:36,640 --> 00:05:39,890
因为对于半径结构来说，这只是你的命令

113
00:05:39,890 --> 00:05:43,813
这很重要，并且全部命名为 title 和 setTitle。

114
00:05:45,204 --> 00:05:47,890
第一个要素，正如我刚才所说，

115
00:05:47,890 --> 00:05:51,110
是该管理值的一个点。

116
00:05:51,110 --> 00:05:54,700
所以最初在 props title 处，存储的值

117
00:05:54,700 --> 00:05:56,120
在道具标题中，

118
00:05:56,120 --> 00:05:57,970
和这里的第二个元素

119
00:05:57,970 --> 00:06:01,720
是一个我们稍后可以调用来设置新标题的函数，

120
00:06:01,720 --> 00:06:04,310
因此，我选择了这个名字。

121
00:06:04,310 --> 00:06:06,380
两个名字都由你决定

122
00:06:06,380 --> 00:06:09,000
但惯例是使用一些东西

123
00:06:09,000 --> 00:06:10,720
它描述了值

124
00:06:10,720 --> 00:06:14,440
作为第一个元素的名称，因为那是值

125
00:06:14,440 --> 00:06:18,140
然后设置，然后重复那个名字

126
00:06:18,140 --> 00:06:20,400
只是这里有一个大写的起始字符。

127
00:06:20,400 --> 00:06:24,740
大写的 T 代表更新值的函数。

128
00:06:24,740 --> 00:06:25,810
这就是约定

129
00:06:25,810 --> 00:06:29,473
关于如何命名 useState 返回的这两个元素。

130
00:06:30,665 --> 00:06:35,480
而 useState 这个钩子总是返回一个数组

131
00:06:35,480 --> 00:06:37,710
正好有两个元素。

132
00:06:37,710 --> 00:06:39,400
情况总是如此。

133
00:06:39,400 --> 00:06:41,360
情况总是如此

134
00:06:41,360 --> 00:06:45,720
第一个元素是当前状态值。

135
00:06:45,720 --> 00:06:49,860
第二个元素是更新它的函数。

136
00:06:49,860 --> 00:06:52,880
现在，我们可以删除该标题变量

137
00:06:52,880 --> 00:06:56,350
我们还可以删除该值分配

138
00:06:56,350 --> 00:06:57,483
在 clickHandler.

139
00:06:58,640 --> 00:07:02,423
我们仍然可以在 JSX 中使用这样的标题。

140
00:07:03,550 --> 00:07:05,790
所以如果我们现在像这样保存它，

141
00:07:05,790 --> 00:07:08,060
我们仍然在这里看到卫生纸。

142
00:07:08,060 --> 00:07:10,110
所以这一点没有改变，

143
00:07:10,110 --> 00:07:12,510
但当然按钮仍然没有任何作用

144
00:07:12,510 --> 00:07:16,240
因为目前我们永远不会更新这个。

145
00:07:16,240 --> 00:07:20,035
现在，正如我所说，使用 useState 返回的值，

146
00:07:20,035 --> 00:07:23,560
我们不会分配带有等号的新值。

147
00:07:23,560 --> 00:07:28,090
相反，我们通过调用 setTitle 分配一个新值。

148
00:07:28,090 --> 00:07:31,280
所以通过调用这个状态更新函数

149
00:07:32,430 --> 00:07:35,180
然后我们刚刚传递了一个新值

150
00:07:35,180 --> 00:07:37,933
作为参数，在本例中已更新。

151
00:07:39,270 --> 00:07:41,210
现在，为什么它会这样工作呢？

152
00:07:41,210 --> 00:07:44,220
为什么我们有这个状态更新功能

153
00:07:44,220 --> 00:07:46,733
而不是像这样分配一个新值？

154
00:07:47,690 --> 00:07:50,670
原因是调用这个函数

155
00:07:50,670 --> 00:07:55,090
不只是为某个变量分配新值，

156
00:07:55,090 --> 00:07:58,950
但它首先是一个特殊的变量。

157
00:07:58,950 --> 00:08:02,230
它由内存中某处的 React 管理。

158
00:08:02,230 --> 00:08:05,300
当我们调用这个状态更新函数时，

159
00:08:05,300 --> 00:08:10,090
这个特殊变量不仅会收到新值

160
00:08:10,090 --> 00:08:12,370
但是，这一点很重要，

161
00:08:12,370 --> 00:08:15,550
您调用的组件函数

162
00:08:15,550 --> 00:08:17,440
这个状态更新函数。

163
00:08:17,440 --> 00:08:20,590
并在其中使用 useState 初始化状态

164
00:08:21,760 --> 00:08:23,323
将再次被执行。

165
00:08:24,250 --> 00:08:26,570
这正是我们所需要的。

166
00:08:26,570 --> 00:08:29,720
我们想再次调用这个组件函数

167
00:08:29,720 --> 00:08:32,090
当我们的状态发生变化时。

168
00:08:32,090 --> 00:08:34,870
并通过调用这个状态更新函数

169
00:08:34,870 --> 00:08:36,429
这正在发生。

170
00:08:36,429 --> 00:08:38,159
因为通过调用这个函数，

171
00:08:38,159 --> 00:08:41,880
你告诉 React 你想分配一个新值

172
00:08:41,880 --> 00:08:43,240
到这个状态。

173
00:08:43,240 --> 00:08:45,790
这也告诉了 React

174
00:08:45,790 --> 00:08:49,560
注册此 staid 的组件

175
00:08:49,560 --> 00:08:53,920
应该重新评估 useState 。

176
00:08:53,920 --> 00:08:56,060
因此 React 将会继续

177
00:08:56,060 --> 00:08:58,680
并再次执行该组件函数，

178
00:08:58,680 --> 00:09:03,620
因此还要再次评估此 JSX 代码。

179
00:09:03,620 --> 00:09:07,710
然后它会绘制它检测到的任何变化

180
00:09:07,710 --> 00:09:12,710
与上次在屏幕上评估时相比。

181
00:09:12,760 --> 00:09:14,700
所以如果我们现在保存一切

182
00:09:14,700 --> 00:09:16,370
如果我点击更改标题，

183
00:09:16,370 --> 00:09:19,150
您会看到标题更改为已更新

184
00:09:19,150 --> 00:09:22,600
对于我们正在执行此操作的 ExpenseItem。

185
00:09:22,600 --> 00:09:25,423
这就是现在的运作方式。

186
00:09:27,070 --> 00:09:29,720
现在你会注意到这些控制台锁

187
00:09:29,720 --> 00:09:33,470
仍然显示更新前的标题。

188
00:09:33,470 --> 00:09:35,613
这样做的原因是调用

189
00:09:35,613 --> 00:09:37,670
这个状态更新函数

190
00:09:37,670 --> 00:09:40,540
实际上并不会立即改变值，

191
00:09:40,540 --> 00:09:44,330
而是安排此状态更新。

192
00:09:44,330 --> 00:09:46,390
所以在接下来的一行中，

193
00:09:46,390 --> 00:09:49,240
这个新值尚不可用。

194
00:09:49,240 --> 00:09:51,610
这就是为什么我们看到旧值被锁定

195
00:09:51,610 --> 00:09:54,900
即使我们在登录之前更新了它。

196
00:09:54,900 --> 00:09:56,170
但你确实看到了

197
00:09:56,170 --> 00:09:59,180
最终这个组件会被再次调用

198
00:09:59,180 --> 00:10:00,980
并再次进行评估。

199
00:10:00,980 --> 00:10:05,980
因此我们可以在屏幕上看到更新后的值。

200
00:10:06,120 --> 00:10:08,330
这就是 React 状态的工作原理。

201
00:10:08,330 --> 00:10:12,170
这是 React 中的另一个关键概念。

202
00:10:12,170 --> 00:10:15,380
如果您有可能会发生变化的数据，

203
00:10:15,380 --> 00:10:18,560
以及应在何处反映该数据的更改

204
00:10:18,560 --> 00:10:20,370
在用户界面上

205
00:10:20,370 --> 00:10:22,900
那么你需要状态

206
00:10:22,900 --> 00:10:25,980
因为常规变量无法解决问题

207
00:10:25,980 --> 00:10:30,050
与状态，但是您可以设置和更改值。

208
00:10:30,050 --> 00:10:31,510
当他们真的改变时，

209
00:10:31,510 --> 00:10:34,220
React 将重新评估组件

210
00:10:34,220 --> 00:10:36,400
国家注册地。

211
00:10:36,400 --> 00:10:39,010
顺便说一下，只有那个组件

212
00:10:39,010 --> 00:10:40,820
没有任何其他组件，

213
00:10:40,820 --> 00:10:45,270
就是注册了该状态的组件。

214
00:10:45,270 --> 00:10:47,070
现在让我们仔细看看

215
00:10:47,070 --> 00:10:49,380
at 状态以及为什么我们使用 const。

216
00:10:49,380 --> 00:10:51,563
以及所有细节如何运作。


